package com.android.qjpmc.widget.loopviewpage;

import android.annotation.TargetApi;
import android.content.Context;
import android.database.DataSetObserver;
import android.os.Build;
import android.os.Handler;
import android.os.Message;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.DecelerateInterpolator;
import android.view.animation.Interpolator;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;
import android.widget.Scroller;
import android.widget.TextView;

import com.android.qjpmc.R;
import com.android.qjpmc.widget.utils.DisplayUtils;

import java.lang.ref.WeakReference;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

import androidx.annotation.NonNull;
import androidx.viewpager.widget.ViewPager;

/**
 * 手动自动可以滚动
 *
 * @since 1.0
 */
public abstract class AutoLoopSwitchBaseView extends RelativeLayout implements ViewPager.OnPageChangeListener {

    private final int VIEWPAGER_SCROLL_DURTION = 400;

    ViewPager mViewPager;
    //protected PageShowView mPageShowView;

    private View mFailtView;
    //
    private int mCurrentItem = 0;

    LoopHandler mHandler;

    private boolean mIsDragging = false;

    private AutoLoopSwitchBaseAdapter mPagerAdapter;

    //监听数据变化，用于去除 重试View
    private DataSetObserver mObserver;
    public int pointNormalBg = R.drawable.shape_gray_cc_point;
    public int pointSelectBg = R.drawable.shape_orange_f69c_point;

    //正在切页
    private boolean isLoopSwitch = false;

    private boolean mCurrentVisible = true;
    private List<TextView> textPointList;
    private boolean mIsPointView = false;
    private PageShowView mPageShowView;
    private LinearLayout layout;

    public void setAddPoint(boolean addPoint) {
        isAddPoint = addPoint;
    }

    private boolean isAddPoint = true;

    public AutoLoopSwitchBaseView(Context context) {
        super(context);
        initView();
    }

    public AutoLoopSwitchBaseView(Context context, AttributeSet attrs) {
        super(context, attrs);
        initView();
    }

    public AutoLoopSwitchBaseView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initView();
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    AutoLoopSwitchBaseView(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
        initView();
    }

    /**
     * 页面切换回调
     *
     * @param model adapter getItem
     */
    protected abstract void onSwitch(int index, Object model);

    /**
     * 滚动延时时间
     */
    protected abstract long getDurtion();

    /**
     * 如果需要网络异常处理
     */
    protected abstract View getFailtView();

    @Override
    protected void onVisibilityChanged(@NonNull View changedView, int visibility) {
        super.onVisibilityChanged(changedView, visibility);
        mCurrentVisible = visibility == VISIBLE;
    }

    public boolean isCurrentVisible() {
        return mCurrentVisible;
    }

    public void setCurrentVisible(boolean mCurrentVisible) {
        this.mCurrentVisible = mCurrentVisible;
    }


    private void initView() {
        mViewPager = new ViewPager(getContext());
        mViewPager.setId(R.id.autoloopswitch_viewpager_id);
        mViewPager.setFocusableInTouchMode(false);
     /*   if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
            mViewPager.setNestedScrollingEnabled(false);
        }*/
        mViewPager.addOnPageChangeListener(this);
        addView(mViewPager, generalLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        mViewPager.setOffscreenPageLimit(2);
        controlViewPagerSpeed();

        mHandler = new LoopHandler(this);
    }

/*
    private void initView() {
        mViewPager = new ViewPager(getContext());
        mViewPager.setId(R.id.autoloopswitch_viewpager_id);
        mViewPager.addOnPageChangeListener(this);
        addView(mViewPager, generalLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
        controlViewPagerSpeed();

        LayoutParams params;
        mPageShowView = new PageShowView(getContext());
        mPageShowView.setId(R.id.autoloopswitch_pagershow_id);
        DisplayMetrics displayMetrics = new DisplayMetrics();
        WindowManager windowManager = (WindowManager) getContext().getSystemService(Context.WINDOW_SERVICE);
        windowManager.getDefaultDisplay().getMetrics(displayMetrics);
        params = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, (int) TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 10, displayMetrics));
        params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        params.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
        addView(mPageShowView, params);

        mHandler = new LoopHandler(this);
    }
*/


    private LayoutParams generalLayoutParams(int w, int h) {
        return new LayoutParams(w, h);
    }

    @Override
    public void onPageScrolled(int i, float v, int i1) {

    }

    @Override
    public void onPageSelected(int i) {

        if (isLoopSwitch) {
            isLoopSwitch = false;
            return;
        }

        mCurrentItem = i;

        int datacount = mPagerAdapter.getDataCount();

        if (datacount > 1) {
            int index = mPagerAdapter.getActualIndex(i) % datacount;
            setTextPointListBg(index);
            // mPageShowView.setCurrentView(index, datacount);
            onSwitch(index, mPagerAdapter.getItem(index));
        }

    }

    private void setTextPointListBg(int index) {
        if (textPointList == null || textPointList.size() == 0) return;
        setTextPointSelectBg(textPointList.get(index));
        for (int x = 0; x < textPointList.size(); x++) {
            if (x != index) {
                setTextPointNormalBg(textPointList.get(x));
            }
        }
    }

    @Override
    public void onPageScrollStateChanged(int i) {

        if (i == ViewPager.SCROLL_STATE_DRAGGING) {
            mIsDragging = true;
        } else if (i == ViewPager.SCROLL_STATE_IDLE) {
            if (mViewPager.getCurrentItem() == 0) {
                isLoopSwitch = true;
                mViewPager.setCurrentItem(mPagerAdapter.getCount() - 2, false);
            } else if (mViewPager.getCurrentItem() == mPagerAdapter.getCount() - 1) {
                isLoopSwitch = true;
                mViewPager.setCurrentItem(1, false);
            }
            mCurrentItem = mViewPager.getCurrentItem();

            if (mIsDragging && mHandler != null) {
                //如果从dragging状态到不是mIsDragging
                mHandler.sendEmptyMessageDelayed(LoopHandler.MSG_UPDATE, getDurtion());
            }

            mIsDragging = false;

        }
    }


    private void notifyDataSetChanged() {
        if (mPagerAdapter != null) {
            int datacount = mPagerAdapter.getDataCount();

            int currentIndex = 0;
            if (datacount > 1) {
                mCurrentItem = mPagerAdapter.getCount() / 2;
                currentIndex = mPagerAdapter.getActualIndex(mCurrentItem) % datacount;
            } else {
                mCurrentItem = 1;
                currentIndex = 0;
            }
            mViewPager.setCurrentItem(mCurrentItem);
            // mPageShowView.setCurrentView(currentIndex, datacount);
            setTextPointListBg(currentIndex);
            if (mFailtView != null && datacount > 0) {
                removeView(mFailtView);
                mFailtView = null;
            }

            updateView();
        }
    }

    private void updateView() {
        for (int i = 0; i < mViewPager.getChildCount(); i++) {
            View v = mViewPager.getChildAt(i);
            if (v != null) {
                int position = (Integer) v.getTag();
                mPagerAdapter.updateView(v, position);
            }
        }

    }


    public void setAdapter(AutoLoopSwitchBaseAdapter adapter) {
        if (mPagerAdapter != null) {
            mPagerAdapter.unregisterDataSetObserver(mObserver);
        }
        this.mPagerAdapter = adapter;
        if (mPagerAdapter != null) {
            if (mObserver == null) {
                mObserver = new PagerObserver();
            }
            mPagerAdapter.registerDataSetObserver(mObserver);

            if (mViewPager != null) {
                mViewPager.setAdapter(mPagerAdapter);
            }
            //如果没有数据，同时没有网络的情况
            if (mPagerAdapter.getDataCount() <= 0) {
                mFailtView = getFailtView();
                if (mFailtView != null) {
                    addView(mFailtView, generalLayoutParams(LayoutParams.MATCH_PARENT, LayoutParams.MATCH_PARENT));
                }
                return;
            }
            addPointView();
        } else {
            throw new NullPointerException("AutoLoopSwitchBaseAdapter can not null");
        }
    }

    public void setIsPointViewDefulte(boolean mIsPointView) {
        this.mIsPointView = mIsPointView;
    }

    private void addPointView() {
        if (!isAddPoint) {
            return;
        }
        if (layout != null) {
            removeView(layout);
            layout = null;
        }
        int childCount = mPagerAdapter.getDataCount();
        if (childCount == 1) return;
        RelativeLayout.LayoutParams frameParams = new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, (int) DisplayUtils.getDimension(R.dimen.dp_5));
        frameParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
        frameParams.addRule(RelativeLayout.CENTER_HORIZONTAL);
        layout = new LinearLayout(getContext());
        textPointList = new ArrayList<>();
        if (mIsPointView) {
            frameParams.bottomMargin = DisplayUtils.dip2px(15);
            if (childCount > 1) {
                layout.setBackgroundResource(R.drawable.shape_gray_56_6dp);
                for (int i = 0; i < childCount; i++) {
                    TextView textPoint = new TextView(getContext());
                    setTextPointNormalBg(textPoint);
                    LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(DisplayUtils.dip2px(6), DisplayUtils.dip2px(6));
                    if (i == 0) {
                        params.setMargins(DisplayUtils.dip2px(9), DisplayUtils.dip2px(4), 0, DisplayUtils.dip2px(3));
                    } else if (i == childCount - 1) {
                        params.setMargins(DisplayUtils.dip2px(5), DisplayUtils.dip2px(4), DisplayUtils.dip2px(9), DisplayUtils.dip2px(3));
                    } else {
                        params.setMargins(DisplayUtils.dip2px(5), DisplayUtils.dip2px(4), 0, DisplayUtils.dip2px(3));
                    }
                    layout.addView(textPoint, params);
                    textPointList.add(textPoint);
                }

            }

        } else {
            frameParams.bottomMargin = DisplayUtils.dip2px(8);
            frameParams.rightMargin = DisplayUtils.dip2px(30);
            for (int i = 0; i < childCount; i++) {
                TextView textPoint = new TextView(getContext());
                setTextPointNormalBg(textPoint);
                LinearLayout.LayoutParams params = new LinearLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
                params.setMargins(0, 0, DisplayUtils.dip2px(4), 0);
                layout.addView(textPoint, params);
                textPointList.add(textPoint);
            }
        }

        setTextPointSelectBg(textPointList.get(0));
        addView(layout, frameParams);
    }

    private void setTextPointBg(TextView textPoint, int res) {
        textPoint.setBackgroundResource(res);
    }

    private void setTextPointSelectBg(TextView textPoint) {
        setTextPointBg(textPoint, textPointSelectBg);
    }

    private void setTextPointNormalBg(TextView textPoint) {
        setTextPointBg(textPoint, textPointNormalBg);
    }

    private int textPointNormalBg = R.drawable.shape_white_point;
    private int textPointSelectBg = R.drawable.shape_orange_ed6b_point;

    public void onDestory() {
        mCurrentItem = 0;
        if (mHandler != null) {
            if (mHandler.mView != null) {
                mHandler.mView.clear();
                mHandler.mView = null;
            }

            mHandler.close();

            mHandler = null;
        }
    }

    public void onStopHandler() {
        if (mHandler != null && !isHandlerStop()) {
            mHandler.stopHandler();
        }
    }

    public void onStartHandler() {
        if (mHandler != null && isHandlerStop()) {
            mHandler.startHandler();
        }
    }

    private boolean isHandlerStop() {
        return mHandler != null && mHandler.isStop();
    }

    protected static class LoopHandler extends Handler {
        //请求更新显示的View。
        private static final int MSG_UPDATE = 1;
        //请求暂停轮播。
        public static final int MSG_STOP = 2;
        //请求恢复轮播。
        public static final int MSG_REGAIN = 3;

        private WeakReference<AutoLoopSwitchBaseView> mView;

        private boolean mIsStop = false;

        public LoopHandler(AutoLoopSwitchBaseView mView) {
            this.mView = new WeakReference<>(mView);
        }


        public boolean isStop() {
            return mIsStop;
        }

        public void close() {
            removeMessages(MSG_UPDATE);
            removeMessages(MSG_REGAIN);
            removeMessages(MSG_STOP);
        }

        public void stopHandler() {
            sendEmptyMessage(MSG_STOP);
        }

        public void startHandler() {
            sendEmptyMessage(MSG_REGAIN);
        }

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            if (mView == null) {
                return;
            }
            if (mView.get() == null) return;
            if (mView.get().mHandler == null || mView.get().mPagerAdapter == null || mView.get().mIsDragging)
                return;
            switch (msg.what) {
                case MSG_UPDATE:
                    if (mIsStop || hasMessages(MSG_UPDATE)) {
                        return;
                    }
                    if (mView.get().mPagerAdapter.getCount() > 1) {
                        mView.get().mCurrentItem++;
                        mView.get().mCurrentItem %= mView.get().mPagerAdapter.getCount();

                        mView.get().mViewPager.setCurrentItem(mView.get().mCurrentItem, true);
                        sendEmptyMessageDelayed(MSG_UPDATE, mView.get().getDurtion());

                    }
                    break;
                case MSG_STOP:
                    if (hasMessages(MSG_UPDATE)) {
                        removeMessages(MSG_UPDATE);
                    }
                    mIsStop = true;
                    break;
                case MSG_REGAIN:
                    if (hasMessages(MSG_UPDATE)) {
                        removeMessages(MSG_UPDATE);
                    }
                    sendEmptyMessageDelayed(MSG_UPDATE, mView.get().getDurtion());
                    mIsStop = false;
                    break;
            }
        }
    }

    private class PagerObserver extends DataSetObserver {
        private PagerObserver() {
        }

        public void onChanged() {
            notifyDataSetChanged();
        }

        public void onInvalidated() {
            Log.e("ryze", "PagerObserver onInvalidated ");

            notifyDataSetChanged();
        }
    }


    public ViewPager getViewPager() {
        return mViewPager;
    }


    private void controlViewPagerSpeed() {
        try {
            Field mField;

            mField = ViewPager.class.getDeclaredField("mScroller");
            mField.setAccessible(true);

            FixedSpeedScroller mScroller = new FixedSpeedScroller(getContext(),
                    new DecelerateInterpolator());
            mScroller.setmDuration(VIEWPAGER_SCROLL_DURTION);
            mField.set(mViewPager, mScroller);

            mField = ViewPager.class.getDeclaredField("mFlingDistance");
            mField.setAccessible(true);
            mField.set(mViewPager, 20);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }


    private class FixedSpeedScroller extends Scroller {

        private int mDuration = 600; // default time is 600ms

        public FixedSpeedScroller(Context context) {
            super(context);
        }

        public FixedSpeedScroller(Context context, Interpolator interpolator) {
            super(context, interpolator);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy, int duration) {
            // Ignore received duration, use fixed one instead
            super.startScroll(startX, startY, dx, dy, mDuration);
        }

        @Override
        public void startScroll(int startX, int startY, int dx, int dy) {
            // Ignore received duration, use fixed one instead
            super.startScroll(startX, startY, dx, dy, mDuration);
        }

        /**
         * set animation time
         */
        public void setmDuration(int time) {
            mDuration = time;
        }

        /**
         * get current animation time
         */
        public int getmDuration() {
            return mDuration;
        }
    }

}
